package models;

import java.util.*;

import javax.persistence.*;
import javax.swing.ListModel;

import play.data.validation.Email;
import play.data.validation.Password;
import play.data.validation.Required;
import play.db.jpa.*;

/**
 * 
 * @author Islam Al-Aarag
 * @version 1.0
 * 
 */
@Entity
public class User extends Model {
	@Required
	public String name;
	@Required
	public String gender;
	@Required
	public String userName;
	@Required
	@Password
	public String password;
	@Required
	public Date dateOfBirth;
	@Required
	@Email
	public String email;
	public String address;
	public int contribution;
	@OneToMany(mappedBy = "creator", cascade = CascadeType.PERSIST)
	public List<Plan> plans;
	@OneToMany(mappedBy = "owner", cascade = CascadeType.PERSIST)
	public List<ActionLog> actions;
	@OneToMany(mappedBy = "marker", cascade = CascadeType.PERSIST)
	public List<DuplicateMark> duplicateMarks;
	@ManyToMany
	public List<Idea> subscribedIdeas;
	@ManyToMany
	public List<ActionItem> actionItems;
	@OneToMany(mappedBy = "creator")
	public List<Topic> createdTopics;
	@ManyToMany
	public List<Topic> subscribedTopics;

	@ManyToMany(mappedBy = "notified")
	public List<Notification> notifications;
	@OneToMany(mappedBy = "creator")
	public List<Idea> createdIdeas;
	@OneToMany(mappedBy = "creator")
	public List<Comment> createdComments;
	@ManyToMany
	public List<Tag> subscribedTags;
	@OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST)
	public List<IdeaRating> ideasRatings;
	@OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST)
	public List<RoleInOrganization> rolesAndOrganization;
	@OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST)
	public List<RoleInEntity> rolesAndEntities;
	@ManyToMany
	@JoinTable(name = "UserFollowOrganization")
	public List<Organization> followedOrgs;
	@ManyToMany
	@JoinTable(name = "UserFollowEnt")
	public List<EEntity> followedEnts;
	@ManyToMany(mappedBy = "followingUsers")
	public List<Topic> followedTopics;
	@ManyToMany
	public List<Topic> allowedTopics;
	@OneToMany
	public List<PlanRating> plansRatings;
	@OneToMany
	public List<TopicRating> topicsRatings;
	@OneToMany(mappedBy = "recievingUser", cascade = CascadeType.PERSIST)
	public List<Request> invitations;
	@OneToMany(mappedBy = "sendingUser", cascade = CascadeType.PERSIST)
	public List<Request> sentRequests;
	@ManyToMany(cascade = CascadeType.PERSIST)
	public List<MergeRequest> mergeRequestsRecieved;
	@OneToMany(mappedBy = "sender", cascade = CascadeType.PERSIST)
	public List<MergeRequest> mergeRequestsSent;
	@OneToMany(mappedBy = "sharedWith")
	public List<SharedIdea> sharedIdeas;
	@OneToMany(mappedBy = "sharedWith")
	public List<SharedTopic> sharedTopics;
	@OneToMany(mappedBy = "sharedWith")
	public List<SharedPlan> sharedPlans;
	@ManyToMany
	public List<User> blockedUsers;

	@ManyToMany(mappedBy = "featuredFor")
	public List<Topic> featuredTopics;

	@ManyToMany(mappedBy = "featuredFor")
	public List<Idea> featuredIdeas;

	@ManyToMany
	@JoinTable(name = "UserBlockedOrganization")
	public List<Organization> blockedOrganizations;
	/** status of being blocked by an organizer from active participation */
	public boolean blocked;
	@ManyToMany(mappedBy = "blockedFromEntity")
	public List<EEntity> blockedEntities;
	
	@OneToOne
	public Picture userPicture;
	public String profileVisibility;

	/**
	 * 
	 * @param name
	 *            full name if the user
	 * @param gender
	 *            gender of the user
	 * @param userName
	 *            the log in user name if the user
	 * @param password
	 *            the password of the user for log in
	 * @param dateOfBirth
	 *            the date if birth of the user
	 * @param email
	 *            the e-mail of the user
	 * @param address
	 *            the address of the user
	 */
	public User(String name, String gender, String userName, String password,
			Date dateOfBirth, String email, String address) {
		this.name = name;
		this.gender = gender;
		this.userName = userName;
		this.password = password;
		this.dateOfBirth = dateOfBirth;
		this.email = email;
		this.address = address;
		this.contribution = 0;
		plans = new ArrayList<Plan>();
		duplicateMarks = new ArrayList<DuplicateMark>();
		subscribedIdeas = new ArrayList<Idea>();
		actionItems = new ArrayList<ActionItem>();
		createdTopics = new ArrayList<Topic>();
		subscribedTopics = new ArrayList<Topic>();
		notifications = new ArrayList<Notification>();
		createdIdeas = new ArrayList<Idea>();
		createdComments = new ArrayList<Comment>();
		subscribedTags = new ArrayList<Tag>();
		rolesAndOrganization = new ArrayList<RoleInOrganization>();
		rolesAndEntities = new ArrayList<RoleInEntity>();
		ideasRatings = new ArrayList<IdeaRating>();
		allowedTopics = new ArrayList<Topic>();
		followedEnts = new ArrayList<EEntity>();
		followedTopics = new ArrayList<Topic>();
		followedOrgs = new ArrayList<Organization>();
		plansRatings = new ArrayList<PlanRating>();
		topicsRatings = new ArrayList<TopicRating>();
		invitations = new ArrayList<Request>();
		blockedUsers = new ArrayList<User>();
		blockedEntities = new ArrayList<EEntity>();
		blockedOrganizations = new ArrayList<Organization>();
		sharedIdeas = new ArrayList<SharedIdea>();
		sharedPlans = new ArrayList<SharedPlan>();
		sharedTopics = new ArrayList<SharedTopic>();
		profileVisibility = "";
		featuredTopics = new ArrayList<Topic>();
		featuredIdeas = new ArrayList<Idea>();
		mergeRequestsRecieved = new ArrayList<MergeRequest>();
		mergeRequestsSent = new ArrayList<MergeRequest>();
		sentRequests = new ArrayList<Request>();
		
	}

	/**
	 * method to add new ideaRating instance to the list of idea ratings
	 * 
	 * @param iR
	 *            the new IdeaRating instance
	 * @return return this instance of user
	 */
	public User addIdeaRating(IdeaRating iR) {
		ideasRatings.add(iR);
		// this.save();
		return this;
	}

	/**
	 * method to add new role instance to the list of oraganization roles of the
	 * user
	 * 
	 * @param rIO
	 *            the new RoleInOrganization instance
	 * @return this instance of user
	 */
	public User addRoleInOrganization(RoleInOrganization rIO) {
		rolesAndOrganization.add(rIO);
		this.save();
		return this;
	}

	public User addRoleInEntity(RoleInEntity rIO) {

		rolesAndEntities.add(rIO);
		this.save();

		User user = rIO.user;

		if (user.isOrganizer(rIO.entity.id)) {

			user.followedEnts.add(rIO.entity);
			rIO.entity.followingUsers.add(this);
			user.save();
			rIO.save();

		}

		return this;
	}

	/**
	 * A method to add a new duplicate mark that this {@link User} has done.
	 * 
	 * @param dup
	 *            the instance of {@link DuplicateMark} that should be assigned
	 *            to this {@link User}
	 * @return this instance of {@link User}
	 */
	public User addDuplicateMark(DuplicateMark dup) {
		duplicateMarks.add(dup);
		this.save();
		return this;
	}

	/**
	 * A method to get a list of users ordered by community contribution.
	 * 
	 * @return a list of users, ordered by community contribution
	 */
	public static List<User> getListOfOrderedUsers() {
		return User.find("order by contribution desc").fetch();
	}

	/**
	 * A method to get the object User given its user name.
	 * 
	 * @author Omar Darwish
	 * @param name
	 *            The user name of required user.
	 * @return The object user with the given user name.
	 */
	public static User getUserInfo(String name) {
		return User.find("byUserName", name).first();
	}

	/**
	 * @author Zeyad Gasser
	 * @userStory 8
	 * @component C1 gets a User by his email
	 * 
	 * @param email
	 *            , the email used to fetch the user from the database
	 * @return User
	 */
	public static User getUserByEmail(String email) {
		return User.find("byEmail", email).first();
	}

	/**
	 * A method that gets the list of users of all organizations
	 * 
	 * @author Alaa Tarek
	 * @return returns a list of users of all organizations
	 */
	public static List<User> getUsers() {
		List<User> temp = User.getListOfOrderedUsers();
		List<User> result = new ArrayList<User>();
		for (int i = 0; i < temp.size(); i++) {
			if (!(temp.get(i).rolesAndOrganization.size() == 0)) {
				result.add(temp.get(i));
			}
		}
		return result;
	}

	/**
	 * A method that checks whether the calling user is the organizer of the
	 * input entity and whether the organization to which the entity belongs is
	 * Secret to decide whether the user can send invitations to idea developers
	 * to join the entity in the secret organization
	 * 
	 * @param entID
	 *            The ID of the entity to be checked on
	 * 
	 * @return A boolean value representing the authority
	 * 
	 * 
	 * */
	public boolean inviteToSecretOrgEntity(long entID) {
		boolean permitted = false;
		EEntity entity = EEntity.find("byID", entID).first();
		if (entity == null)
			return false;
		for (RoleInEntity roleinentity : rolesAndEntities) {
			if (roleinentity.role.description.equalsIgnoreCase("Organizer")
					&& entity.equals(roleinentity.entity)) {
				permitted = true;
			}
		}
		return permitted && entity.organization.isSecret();
	}

	/**
	 * A method that checks whether a user is an organization lead of a certain
	 * organization and whether the organization is a secret one.
	 * 
	 * @param orgID
	 *            The id of the organization
	 * @param userID
	 *            the id of the user
	 * @return returns a boolean variable permitted
	 * */
	public boolean inviteToSecretOrg(long orgID, long userID) {
		Organization org = Organization.find("byID", orgID).first();
		if (org == null)
			return false;
		boolean permitted = false;
		RoleInOrganization role = new RoleInOrganization(org, this, new Role(
				"Organization Lead"));
		if (this.rolesAndOrganization.contains(role)) {
			permitted = true;
		}
		return permitted && org.isSecret();
	}

	public boolean equals(Object o) {
		if (o instanceof User) {
			return ((User) o).id == this.id;
		}
		return false;
	}

	/**
	 * A method that returns one user's email address
	 * 
	 * @return A String value representing the user's email address
	 * 
	 * @author Johannes Schmidt
	 * 
	 * */
	public String getEmail() {
		return this.email;
	}

	public boolean relateToEntity(EEntity userEntity, EEntity relateEntity,
			String name, String Description) {// a method to relate an entity to
												// another entity

		if (!relateEntity.checkLock()) {
			RelatedEntities relation = new RelatedEntities(userEntity,
					relateEntity, name, Description);
			userEntity.relations.add(relation);
			return true;
		} else
			return false;
	}

	/**
	 * @author Hesham Al-Razaz This method relates two topics together
	 * 
	 * @param userTopic
	 *            the user's Topic
	 * @param relateTopic
	 *            the topic i want to relate to
	 * @return boolean value for weather the user can relate to this relatetopic
	 *         or not
	 * */

	public boolean relateToTopic(Topic userTopic, Topic relateTopic,
			TopicRelationNames relationName) {
		if (!relateTopic.checkLock()) {
			userTopic.relatedTopicList.add(relateTopic);
			relateTopic.relatedTopicList.add(userTopic);
			relateTopic.save();
			userTopic.save();
			userTopic.relationNames.add(relationName);
			relateTopic.relationNames.add(relationName);
			relateTopic.save();
			userTopic.save();

			return true;
		} else

			return false;
	}

	/**
	 * @author Hesham Al-Razaz
	 * 
	 *         This method removes the relation between two topics
	 * 
	 * @param userTopic
	 *            the user's Topic
	 * @param relateTopic
	 *            the topic i want to relate to
	 * @return boolean value for weather the user can relate to this relatetopic
	 *         or not
	 * */

	public boolean removeRelation(Topic userTopic, Topic relateTopic) {

		if (userTopic != null && relateTopic != null) {

			userTopic.relationNames.remove(userTopic.relatedTopicList
					.indexOf(relateTopic));
			relateTopic.relationNames.remove(relateTopic.relatedTopicList
					.indexOf(userTopic));
			userTopic.relatedTopicList.remove(relateTopic);
			relateTopic.relatedTopicList.remove(userTopic);
			userTopic.save();
			relateTopic.save();
			return true;
		} else
			return false;

	}

	/**
	 * 
	 * the method takes a userID and organisation's id and returns whether this
	 * role of this user in this organisation gives him the permission to create
	 * a new tag or not
	 * 
	 * @param userID
	 *            the user's ID
	 * @param orgID
	 *            the organization's ID
	 * @return boolean value whether that role is allowed to do such permission
	 *         or not.
	 * */

	public boolean allowedtoCreateTag(long orgID) {
		Organization org = Organization.find("byID", orgID).first();
		if (org == null)
			return false;
		Role usersrole = null;
		for (RoleInOrganization role : rolesAndOrganization) {
			if (role.organization.id == orgID) {
				usersrole = role.role;
			}
		}
		if (usersrole == null)
			return false;
		List<Permission> RolePermissions = usersrole.allowedPermissions;
		for (Permission permission : RolePermissions) {
			if (permission.description.equalsIgnoreCase("Create tag")) {
				return true;
			}
		}
		return false;
	}

	/**
	 * This method checks if this user is the organization lead of a certain
	 * organization
	 * 
	 * @param orgID
	 *            the ID of the organization to check if is it's lead
	 * @return boolean value true if is organization lead of this organization
	 *         else false
	 */
	public boolean isOrganizationLead(long orgID) {
		Organization org = Organization.find("byID", orgID).first();
		if (org == null)
			return false;
		Role usersrole = null;
		for (RoleInOrganization role : rolesAndOrganization) {
			if (role.organization.id == orgID) {
				usersrole = role.role;
			}
		}
		if (usersrole == null)
			return false;
		if (usersrole.description.equalsIgnoreCase("organizationLead")) {
			return true;
		}
		return false;
	}

	/**
	 * This method checks if this user is the organize of a certain organization
	 * 
	 * @param orgID
	 *            the ID of the organization to check if is it's lead
	 * @return boolean value true if is organizer of this organization else
	 *         false
	 */
	public boolean isOrganizer(long entityID) {
		for (RoleInEntity role : rolesAndEntities) {
			if (role.entity.id == entityID
					&& role.role.description.equals("Organizer")) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @author AkrAmAtion
	 * 
	 * @return a String that will be used to export search results displaying a
	 *         user (organization lead for example) who is responsible for a
	 *         model that matches a keyword. The String is formatted as
	 *         Comma-Separated-Values
	 * */
	public String toString() {
		return "USER," + name;
	}

	/**
	 * A method that returns a boolean variable specifying whether the user
	 * calling the method has followed the organization that is passed to the
	 * method as an input parameter.
	 * 
	 * @author Mostafa Ali
	 * 
	 * @param orgID
	 *            The ID of the organization to check on.
	 * 
	 * @return boolean variable specifying whether the organization has already
	 *         been followed by the user.
	 * 
	 * */

	public boolean hasFollowedOrganization(long orgID) {
		Organization organization = Organization.find("byID", orgID).first();
		if (organization == null)
			return false;
		if (followedOrgs.contains(organization))
			return true;
		return false;
	}

	/**
	 * A method that returns a boolean variable specifying whether the user
	 * calling the method has followed the entity that is passed to the method
	 * as an input parameter.
	 * 
	 * @author Mostafa Ali
	 * 
	 * @param entID
	 *            The ID of the entity to be checked on
	 * 
	 * @return boolean variable specifying whether the entity has already been
	 *         followed by the user.
	 * 
	 * */

	public boolean hasFollowedEntity(long entID) {
		EEntity entity = EEntity.find("byID", entID).first();
		if (entity == null)
			return false;
		if (followedEnts.contains(entity))
			return true;
		return false;
	}

	/**
	 * A method that returns a boolean variable specifying whether the user
	 * calling the method has followed the topic that is passed to the method as
	 * an input parameter.
	 * 
	 * @author Mostafa Ali
	 * 
	 * @param topicID
	 *            The ID of the topic to be checked on.
	 * 
	 * @return boolean variable specifying whether the topic has already been
	 *         followed by the user.
	 * 
	 * */

	public boolean hasFollowedTopic(long topicID) {
		Topic topic = Topic.find("byID", topicID).first();
		if (topic == null)
			return false;
		if (followedTopics.contains(topic))
			return true;
		return false;
	}

	

	/**
	 * Given a user id, it added the user with this id ( if exists) to the list
	 * of blocked user of this user if not already blocked
	 * 
	 * @author Islam Al-Aarag
	 * @story C4S71
	 * @param blockId
	 *            the id of the user to be blocked
	 */
	public void block(long blockedId) {
		User blockedUser = User.findById(blockedId);
		if (blockedUser != null && !blockedUsers.contains(blockedUser)) {
			blockedUsers.add(blockedUser);

			for (int i = 0; i < sharedIdeas.size(); i++) {
				if (sharedIdeas.get(i).sharer.id == blockedId) {
					SharedIdea temp = sharedIdeas.remove(i);
					temp.delete();
					System.out.println("hjo");
					System.out.println(sharedIdeas.size());
					i--;
				}
			}
		}
		this.save();
		System.out.println(sharedIdeas.size());
	}

	/**
	 * Given a user id, it unblocks the user (i.e: remove it from list of
	 * blocked users) if it still exists in the system
	 * 
	 * @author Islam Al-Aarag
	 * @story C4S71
	 * @param blockedId
	 *            the id of the user to be unblocked
	 */
	public void unBlock(long blockedId) {
		User blockedUser = User.findById(blockedId);
		if (blockedUser != null && blockedUsers.contains(blockedUser))
			blockedUsers.remove(blockedUser);
		this.save();
	}

	/**
	 * Given a user id, it checks whether this user has blocked the provided
	 * user or not (non existing users are considered to be blocked s they can't
	 * perform any action)
	 * 
	 * @author Islam Al-Aarag
	 * @story C4S71
	 * @param userId
	 *            the id of the user to check whether blocked or nor
	 * @return boolean true if user is blocked and false otherwise
	 */
	public boolean isBlocked(long userId) {
		User user = User.findById(userId);
		boolean isBlocked = user != null && blockedUsers.contains(user);
		return isBlocked;
	}

	/**
	 * check whether the logged in user is the system admin
	 * 
	 * @author Omar Darwish
	 * @return true if the logged in user is the system admin or false otherwise
	 * 
	 */
	public boolean isSysteAdmin() {
		if (userName.equalsIgnoreCase("System Admin"))
			return true;
		return false;
	}

	/**
	 * the method goes through the followed Ideas, Topics, and through created
	 * topics, Ideas, and action items and get all the tags in these Objects
	 * then order the tags according to its Count
	 * 
	 * @returns Sorted List of @see <code>ObjectWithCount</code> which contains
	 *          the tag name with its count
	 * 
	 * @author Ahmed Mahmoud
	 */
	public List<ObjectWithCount> getTopTags() {
		HashMap<String, Integer> tagsCount = new HashMap<String, Integer>();
		/**************************************************************/
		HashSet<Idea> userIdeasWithoutDuplicates = new HashSet<Idea>(
				this.createdIdeas);
		userIdeasWithoutDuplicates.addAll(this.subscribedIdeas);
		for (Idea idea : userIdeasWithoutDuplicates) {
			for (Tag tag : idea.tags) {
				if (tagsCount.containsKey(tag.name)) {
					tagsCount.put(tag.name, tagsCount.get(tag.name) + 1);
				} else {
					tagsCount.put(tag.name, 1);
				}
			}
		}
		userIdeasWithoutDuplicates = null;
		/**************************************************************/
		HashSet<Topic> userTopicsWithoutDuplicates = new HashSet<Topic>(
				this.followedTopics);
		userTopicsWithoutDuplicates.addAll(this.createdTopics);
		for (Topic topic : userTopicsWithoutDuplicates) {
			for (Tag tag : topic.tags) {
				if (tagsCount.containsKey(tag.name)) {
					tagsCount.put(tag.name, tagsCount.get(tag.name) + 1);
				} else {
					tagsCount.put(tag.name, 1);
				}
			}
		}
		userTopicsWithoutDuplicates = null;
		/*************************************************************/
		List<ActionItem> userActionItems = this.actionItems;
		for (ActionItem actionItem : userActionItems) {
			for (Tag tag : actionItem.tags) {
				if (tagsCount.containsKey(tag.name)) {
					tagsCount.put(tag.name, tagsCount.get(tag.name) + 1);
				} else {
					tagsCount.put(tag.name, 1);
				}
			}
		}
		userActionItems = null;
		/*************************************************************/
		Set<String> keys = tagsCount.keySet();
		List<ObjectWithCount> topTags = new ArrayList<ObjectWithCount>();
		for (String key : keys) {
			int count = tagsCount.get(key);
			topTags.add(new ObjectWithCount(key, count));
		}
		Comparator<ObjectWithCount> reversedComparator = Collections
				.reverseOrder(new OrderObjectsByCount());
		Collections.sort(topTags, reversedComparator);
		return topTags;
	}

	/**
	 * @author Ahmed Mahmoud
	 * @return
	 */
	public boolean cascadeDelete() {
		
		for (EEntity entity : blockedEntities) {
			entity.blockedFromEntity.remove(this);
			entity.save();
		}
		for (Organization organization : blockedOrganizations) {
			organization.blockedusers.remove(this);
			organization.save();
		}
		for (User user : blockedUsers) {
			user.blockedUsers.remove(this);
			user.save();
		}
		while (!sharedPlans.isEmpty()) {
			SharedPlan sharedPlan = sharedPlans.get(0);
			sharedPlan.cascadeDelete();
		}
		while (!sharedTopics.isEmpty()) {
			SharedTopic sharedTopic = sharedTopics.get(0);
			sharedTopic.cascadeDelete();
		}
		while (!sharedIdeas.isEmpty()) {
			SharedIdea sharedIdea = sharedIdeas.get(0);
			sharedIdea.cascadeDelete();
		}
		while (!invitations.isEmpty()) {
			Request request = invitations.get(0);
			request.cascadeDelete();
		}
		while (!sentRequests.isEmpty()) {
			Request request = sentRequests.get(0);
			request.cascadeDelete();
		}
		for (MergeRequest mergeRequest : mergeRequestsRecieved) {
			mergeRequest.recievers.remove(this);
			mergeRequest.save();
		}
		while (!mergeRequestsSent.isEmpty()) {
			MergeRequest mergeRequest = mergeRequestsSent.get(0);
			mergeRequest.cascadeDelete();
		}
		while (!topicsRatings.isEmpty()) {
			TopicRating topicRating = topicsRatings.get(0);
			topicRating.cascadeDelete();
		}
		while (!ideasRatings.isEmpty()) {
			IdeaRating ideaRating = ideasRatings.get(0);
			ideaRating.cascadeDelete();
		}
		while (!plansRatings.isEmpty()) {
			PlanRating planRating = plansRatings.get(0);
			planRating.cascadeDelete();
		}
		while (!rolesAndEntities.isEmpty()) {
			RoleInEntity roleInEntity = rolesAndEntities.get(0);
			roleInEntity.cascadeDelete();
		}
		while (!rolesAndOrganization.isEmpty()) {
			RoleInOrganization roleInOrganization = rolesAndOrganization.get(0);
			roleInOrganization.cascadeDelete();
		}
		for (Organization organization : followedOrgs) {
			organization.followingUsers.remove(this);
			organization.save();
		}
		for (EEntity entity : followedEnts) {
			entity.followingUsers.remove(this);
			entity.save();
		}
		for (Topic topic : followedTopics) {
			topic.followingUsers.remove(this);
			topic.save();
		}
		while (!ideasRatings.isEmpty()) {
			IdeaRating ideaRating = ideasRatings.get(0);
			ideaRating.cascadeDelete();
		}
		for (Tag tag : subscribedTags) {
			tag.subscribers.remove(this);
		}
		while (!createdIdeas.isEmpty()) {
			Idea idea = createdIdeas.get(0);
			idea.cascadeDelete();
		}
		for (Notification notification : notifications) {
			notification.notified.remove(this);
			notification.save();
		}

		while (!createdTopics.isEmpty()) {
			Topic topic = createdTopics.get(0);
			topic.cascadeDelete();
		}

		for (ActionItem actionItem : actionItems) {
			actionItem.users.remove(this);
			actionItem.save();
		}
		for (Idea idea : subscribedIdeas) {
			idea.subscribers.remove(this);
		}
		while (!duplicateMarks.isEmpty()) {
			DuplicateMark duplicateMark = duplicateMarks.get(0);
			duplicateMark.cascadeDelete();
		}
		while (!plans.isEmpty()) {
			Plan plan = plans.get(0);
			plan.cascadeDelete();
		}
		for (Topic topic : featuredTopics) {
			topic.featuredFor.remove(this);
			topic.save();
		}
		for (Idea idea : featuredIdeas) {
			idea.featuredFor.remove(this);
			idea.save();
		}
		this.delete();
		return true;
	}
	/**
	*method to check if the user has a profile picture on the system
	*@author Omar fouda
	*@return int, returns -1 if the user has no picture and 0 if he does
	*/	
	public int getPictureId() {
    	Picture picture = this.userPicture;
    	if(picture==null){
    		System.out.println("-1");
    			return -1;
    		}
    	System.out.println("0");
        return 0;
    }
	
}
